package com.chen.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chen.domain.Sms;
import com.chen.domain.User;
import com.chen.domain.UserAuthAuditRecord;
import com.chen.domain.UserAuthInfo;
import com.chen.dto.R;
import com.chen.dto.UserDto;
import com.chen.enums.SMSEnum;
import com.chen.fegin.UserFegin;
import com.chen.model.UnsetPayPasswordVo;
import com.chen.model.UpdateLoginVo;
import com.chen.model.UpdateUserMobileVo;
import com.chen.service.SmsService;
import com.chen.service.UserAuthAuditRecordService;
import com.chen.service.UserAuthInfoService;
import com.chen.service.UserService;
import com.chen.utils.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.xml.bind.ValidationException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @Author: chen
 * @Date: 2021/4/26 10:20 AM
 * @Version 1.0
 */
@RestController
@Api(tags = "用户相关的接口")
@RequestMapping("/users")
@Slf4j
public class UserController implements UserFegin {

    @Autowired
    private UserService userService;

    @Autowired
    private SmsService smsService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Autowired
    private UserAuthInfoService userAuthInfoService;

    @Autowired
    private UserAuthAuditRecordService userAuthAuditRecordService;

    @GetMapping
    @ApiOperation(value = "分页查询用户用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号"),
            @ApiImplicitParam(name = "userId", value = "用户id"),
            @ApiImplicitParam(name = "userName", value = "用户名"),
            @ApiImplicitParam(name = "realName", value = "姓名"),
            @ApiImplicitParam(name = "status", value = "状态"),
            @ApiImplicitParam(name = "current", value = "当前页数"),
            @ApiImplicitParam(name = "size", value = "每页显示条数")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> list(Page<User> page,
                              String moblie,
                              String userId,
                              String userName,
                              String realName,
                              String status
    ) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(moblie)) {
            queryWrapper.like("mobile", moblie);
        }
        if (StringUtils.isNotBlank(userId)) {
            queryWrapper.like("id", userId);
        }
        if (StringUtils.isNotBlank(userName)) {
            queryWrapper.like("username", userName);
        }
        if (StringUtils.isNotBlank(realName)) {
            queryWrapper.like("real_name", realName);
        }
        if (StringUtils.isNotBlank(status)) {
            queryWrapper.eq("status", status);
        }
        queryWrapper.orderByDesc("last_update_time");

        return R.ok(userService.page(page, queryWrapper));
    }

    @PatchMapping
    @ApiOperation(value = "编辑用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authStatus", value = "实名认证状态"),
            @ApiImplicitParam(name = "countryCode", value = "国际区号"),
            @ApiImplicitParam(name = "email", value = "邮箱"),
            @ApiImplicitParam(name = "id", value = "id"),
            @ApiImplicitParam(name = "idCard", value = "身份证号"),
            @ApiImplicitParam(name = "mobile", value = "手机号"),
            @ApiImplicitParam(name = "realName", value = "姓名"),
            @ApiImplicitParam(name = "status", value = "用户状态"),
            @ApiImplicitParam(name = "username", value = "用户名")
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R<Object> update(@ApiIgnore @RequestBody User user) {
        userService.updateById(user);
        return R.ok();

    }

    @PostMapping("/status")
    @ApiOperation(value = "启用/禁用用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id"),
            @ApiImplicitParam(name = "status", value = "状态码")
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R<Object> status(@RequestParam("id") String userId,
                            @RequestParam("status") Byte status) {
        User user = new User();
        user.setId(Long.parseLong(userId));
        user.setStatus(status);
        userService.updateById(user);
        return R.ok();

    }

    @GetMapping("/info")
    @ApiOperation(value = "查询会员的详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<User> status(@RequestParam("id") String userId) {
        User byId = userService.getById(userId);
        return R.ok(byId);

    }

    @GetMapping("/directInvites")
    @ApiOperation(value = "查询该用户邀请的用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "该用户的Id"),
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),

    })
    public R<Page<User>> getDirectInvites(@ApiIgnore Page<User> page, Long userId) {
        Page<User> userPage = userService.findDirectInvitePage(page, userId);
        return R.ok(userPage);
    }

    @GetMapping("/auths")
    @ApiOperation(value = "查询用户的审核列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号"),
            @ApiImplicitParam(name = "userId", value = "用户id"),
            @ApiImplicitParam(name = "userName", value = "用户名"),
            @ApiImplicitParam(name = "realName", value = "姓名"),
            @ApiImplicitParam(name = "reviewsStatus", value = "状态"),
            @ApiImplicitParam(name = "current", value = "当前页数"),
            @ApiImplicitParam(name = "size", value = "每页显示条数")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> auths(Page<User> page,
                               String moblie,
                               String userId,
                               String userName,
                               String realName,
                               String reviewsStatus
    ) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(moblie)) {
            queryWrapper.like("mobile", moblie);
        }
        if (StringUtils.isNotBlank(userId)) {
            queryWrapper.like("id", userId);
        }
        if (StringUtils.isNotBlank(userName)) {
            queryWrapper.like("username", userName);
        }
        if (StringUtils.isNotBlank(realName)) {
            queryWrapper.like("real_name", realName);
        }
        if (StringUtils.isNotBlank(reviewsStatus)) {
            queryWrapper.eq("reviews_status", reviewsStatus);
        }
        queryWrapper.orderByDesc("last_update_time");

        return R.ok(userService.page(page, queryWrapper));

    }

    @GetMapping("/auth/info")
    @ApiOperation(value = "查询用户的认证详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的Id")
    })
    public R<UseAuthInfoVo> authInfo(Long id) {

        User user = userService.getById(id);

        List<UserAuthAuditRecord> userAuthAuditRecords = new ArrayList<>();

        List<UserAuthInfo> list = userAuthInfoService.listUserAuthInfo(id);

        if (CollectionUtils.isEmpty(list)) {
            userAuthAuditRecords = Collections.emptyList();
        } else {
            QueryWrapper<UserAuthAuditRecord> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("user_id", id);
            userAuthAuditRecords = userAuthAuditRecordService.list(queryWrapper1);
        }

        return R.ok(new UseAuthInfoVo(user, list, userAuthAuditRecords));


    }

    @PostMapping("/auths/status")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的ID"),
            @ApiImplicitParam(name = "authStatus", value = "用户的审核状态"),
            @ApiImplicitParam(name = "authCode", value = "一组图片的唯一标识"),
            @ApiImplicitParam(name = "remark", value = "审核拒绝的原因"),
    })
    public R<Object> authsStatus(@RequestParam(required = true) String id,
                                 @RequestParam(required = true) String authStatus,
                                 @RequestParam(required = true) String authCode,
                                 String remark) {

        userService.authsStatus(id, authStatus, authCode, remark);
        return R.ok();

    }


    @GetMapping("/current/info")
    @ApiOperation(value = "获取当前登录用户对象的信息")
    public R<User> info() {
        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        User user = userService.getById(Long.parseLong(userId));
        user.setPassword("**********");
        user.setPaypassword("**********");
        return R.ok(user);
    }

    @PostMapping("/authAccount")
    @ApiOperation(value = "用户的实名认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userAuthForm", value = "userAuthFormjson数据")
    })
    public R<Object> authAccount(@RequestBody User user) throws ValidationException {

        userService.authAccount(user);
        return R.ok();
    }

    @PostMapping("/authUser")
    @ApiOperation(value = "用户进行高级认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "imgs", value = "用户的图片地址")
    })
    public R<Object> authUser(@RequestBody String[] imgas) {
        userService.authUser(imgas);
        return R.ok();
    }

    @PostMapping("/updatePhone")
    @ApiOperation(value = "修改手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateUserMobileVo", value = "updatePhoneParam 的json数据")
    })
    public R<Object> updatePhone(@RequestBody UpdateUserMobileVo updateUserMobileVo) {

        userService.updatePhone(updateUserMobileVo);

        return R.ok();

    }

    @GetMapping("/checkTel")
    @ApiOperation(value = "检查新的手机号是否可用,如可用,则给该新手机发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "新的手机号"),
            @ApiImplicitParam(name = "countryCode", value = "手机号的区域")
    })
    public R<Object> checkTel(String countryCode, String mobile) {

        //1 新的手机号,没有旧的用户使用
        int count = userService.count(new LambdaQueryWrapper<User>().eq(User::getMobile, mobile).eq(User::getCountryCode, countryCode));
        if (count > 0) { // 有用户占用这个手机号
            throw new IllegalArgumentException("该手机号已经被占用");
        }

        Sms sms = new Sms();
        sms.setCountryCode(countryCode);
        sms.setMobile(mobile);
        sms.setTemplateCode(SMSEnum.CHANGE_PHONE_VERIFY.getCode());
        //发送验证码
        smsService.sendTo(sms);

        return R.ok();
    }

    @PostMapping("/updateLoginPassword")
    @ApiOperation(value = "修改用户的登录密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateLoginVo", value = "修改用户的登录密码")
    })
    public R<Object> updateLoginPassword(@RequestBody @Validated UpdateLoginVo updateLoginVo) {

        userService.updateLoginPassword(updateLoginVo);
        return R.ok();

    }

    @PostMapping("/updatePayPassword")
    @ApiOperation(value = "修改用户的交易密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateLoginVo", value = "修改用户的交易密码")
    })
    public R updatePayPwd(@RequestBody @Validated UpdateLoginVo updateLoginVo) {
        userService.updateUserPayPwd(updateLoginVo);
        return R.ok();
    }

    @PostMapping("/setPayPassword")
    @ApiOperation(value = "重新设置交易密码")
    public R setPayPassword(@RequestBody @Validated UnsetPayPasswordVo unsetPayPasswordVo) {
        userService.unsetPayPassword(unsetPayPasswordVo);
        return R.ok();
    }

    @GetMapping("/invites")
    public R<List<User>> invites() {

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("direct_inviteid", UserUtil.getUser());
        userQueryWrapper.orderByDesc("created");

        return R.ok(userService.list(userQueryWrapper));
    }

    @PostMapping("/register")
    public R<Object> register(@RequestBody User user) throws ValidationException {

        userService.register(user);
        return R.ok();

    }

    @PostMapping("/userBase")
    public R<Object> userBase(@RequestBody User user) {
        user.setId(UserUtil.getUser());
        user.setPaypassSetting(1);
        user.setPaypassword(new BCryptPasswordEncoder().encode(user.getPaypassword()));
        userService.updateById(user);
        return R.ok();
    }


    @Override
    @GetMapping("/getUserByIds")
    public Map<Long, UserDto> getUser(List<Long> ids, String username, String mobile,Long page,Long size) {
        return userService.getUser(ids,username,mobile,page,size);
    }


}

@Data
class UseAuthInfoVo {


    private User user;

    private List<UserAuthInfo> userAuthInfoList;

    private List<UserAuthAuditRecord> authAuditRecordList;

    public UseAuthInfoVo(User user,
                         List<UserAuthInfo> userAuthInfos,
                         List<UserAuthAuditRecord> userAuthAuditRecords) {
        this.user = user;
        this.userAuthInfoList = userAuthInfos;
        this.authAuditRecordList = userAuthAuditRecords;
    }
}
